var bounceTwitUserName = "daigotanaka";
var nTweetsToFetch = 9;
var bounceTwitDivID = "myTweets";

var nRows = 4;
var rowInterval = 50;
var maxLettersPerRow = 45;
var bounceTwitLetterWidth = 15;
var bounceTwitLetterHeight = 20;

var bounceTwitTimerID;
var bounceTwitTweetCount = 0;
var bounceTwitUpdateInterval = 10 * 1000;
var bounceTwitRefetchTweetInterval = 300 * 1000;
var bounceTwitLastFetchTweetTime = 0;

function bounceTwit()
{
  bounceTwitLastFetchTweetTime = 0;
  bounceTwitElapsedTime = 0;
  bounceTwitTweetCount = 0;
 
  twitterLetterParticlesOnTimer(); // initial call
  clearInterval( bounceTwitTimerID );
  bounceTwitTimerID = setInterval( twitterLetterParticlesOnTimer, bounceTwitUpdateInterval);
  return true;
}
 
var bounceTwitElapsedTime = 0;
var bounceTwitStatus = 0;
function twitterLetterParticlesOnTimer()
{
  bounceTwitTweetCount %= cachedTweets.length;
 
  document.getElementById(bounceTwitDivID).innerHTML = "";

  if (cachedTweets.length == 0 || bounceTwitElapsedTime >= bounceTwitLastFetchTweetTime + bounceTwitRefetchTweetInterval){
    var url = "http://twitter.com/statuses/user_timeline/"+ bounceTwitUserName + ".json?callback=twitterCacheCallback&count=" + nTweetsToFetch.toFixed(0);
    jQuery.ajax({   type: "GET",   url: url,   dataType: "script" });

    bounceTwitTweetCount = 0;
    bounceTwitLastFetchTweetTime = bounceTwitElapsedTime;
  }
  bounceTwitStatus = 1;
  if (cachedTweets.length == 0){
    if (bounceTwitElapsedTime <= bounceTwitUpdateInterval ){
      // Within the interval...so may be just delayed response from Twitter...
      bounceTwitElapsedTime += bounceTwitUpdateInterval;
      cachedTweets[0] = "Loading " + bounceTwitUserName + "'s tweet now...";
      bounceTwitStatus = 0;
    }
    else{
      // must have been an error
      cachedTweets[0] = "Opps, there was an error in fetching tweets. Try refreshing the browser after a few minutes.";
      bounceTwitStatus = -1;
    }
  }
 
  document.getElementById(bounceTwitDivID).innerHTML = cachedTweets[bounceTwitTweetCount];
 
  twitterLetterParticlesUpdate();
 
  bounceTwitElapsedTime += bounceTwitUpdateInterval;
}
 
 
var bounceTwitPhysicalHtml = new physHtml.main("bounceTwitPhysicalHtml");
function twitterLetterParticlesUpdate()
{  
  if (bounceTwitPhysicalHtml.state == 1){
    bounceTwitPhysicalHtml.stop();
  }
 
  bounceTwitPhysicalHtml = new physHtml.main("bounceTwitPhysicalHtml");
  var urls = document.getElementById(bounceTwitDivID).innerHTML.split("http://");
  var tweetUrl = urls[urls.length - 1].replace(/\".*/ig, "");
  var twitterStatus = document.getElementById(bounceTwitDivID).innerHTML.replace(/(<([^>]+)>)/ig,"");
  document.getElementById(bounceTwitDivID).innerHTML = "";
 
  bounceTwitPhysicalHtml.initialize();  
  bounceTwitPhysicalHtml.maxTime = bounceTwitUpdateInterval - 100;
 
  bounceTwitFactory = new physHtml.wordObjectFactory(bounceTwitPhysicalHtml);
  bounceTwitFactory.gravity = $V([0.0, 10 * 9.8]);
  bounceTwitFactory.offset = $V([-0.5, -0.5]);
  bounceTwitFactory.rotationOffset = $V([0.0, 0.0]);
  var style = "position:absolute; font-size:" + bounceTwitLetterHeight + "px;";
 
  var words = twitterStatus.split(" ");
  var subWords = new Array();
  var index = 0;
  for (i = 0; i < nRows; i++){
    subWords[i] = "";
  }
  for (var i = 0; i < words.length; i++){
    if(words[i].length > maxLettersPerRow){
      words.splice(i + 1, 0, words[i].substring(maxLettersPerRow, words[i].length));
      words[i] = words[i].substring(0, maxLettersPerRow);
    }

    if (subWords[index].length > 0){
      if (subWords[index].length + words[i].length >= maxLettersPerRow
          || (i == words.length - 3 && subWords[index].length + words[i].length + words[i + 1].length + words[i + 2].length >= maxLettersPerRow) ){
      index++;
      }
      else{
        subWords[index] += " ";
      }
    }
    subWords[index] += words[i];
  }
 
  bounceTwitObjects = new Array(nRows);
  for (i = 0; i < nRows; i++){
    var strings = subWords[i].split(" ");
 
    for (j = 0; j < strings.length; j++){
      if (strings[j].substring(0, 7) == "http://"){
        var displayUrl = strings[j];
        if (displayUrl.length > 23){
          displayUrl = displayUrl.substring(0, 20) + "...";
        }
        strings[j] = "<a  href='" + strings[j] + "' target=new>" + displayUrl + "</a>";
      }
 
//      Add link to reply user
      strings[j] = strings[j].replace(/\B@([_a-z0-9]+)/ig, function(reply) { return  reply.charAt(0)+'<a target="new" href="http://twitter.com/'+reply.substring(1)+'">'+reply.substring(1)+'</a>';} );
    }
    if (i == nRows - 1 || subWords[i + 1].length == 0){
      for (j = strings.length - 3; bounceTwitStatus == 1 && j < strings.length; j++){
      strings[j] = '<a href="http://' + tweetUrl + '" target=new >' + strings[j] + '</a>';
      }
    }
 
    var position = $V([0, i * 60]);
    bounceTwitObjects[i] = bounceTwitFactory.createWordObjectsInElement("bounceTwit" + i.toFixed(0), strings, bounceTwitDivID, position, bounceTwitLetterWidth, bounceTwitLetterHeight, style);
  }
 
  var floor = new Array(nRows);
  for (var i = 0; i < nRows; i++){
    floor[i] = new physHtml.wall( $V([1, 50 + rowInterval * i]), 0.0, 1000, 1, 0.8 );
 
    for (var j = 0; j < bounceTwitObjects[i].length; j++){
      bounceTwitObjects[i][j].connect(floor[i], floor[i]);
      bounceTwitObjects[i][j].velocity = $V([0.0, -50 - 5 * (j % 2 + i) ]);
      bounceTwitObjects[i][j].radius = bounceTwitLetterHeight;
    }
   }
 
  if (bounceTwitStatus == 1) bounceTwitTweetCount++;
  bounceTwitPhysicalHtml.start();
}

bounceTwit();

